﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using Yxinmt.Controls;
using Yxinmt.Interface;
using Yxinmt.Utility;

namespace Yxinmt.Windows.Meeting
{

    public class VideoPlay : BaseWindow, IWindow
    {
        public Guid MeetingId { get; set; }

        Index _Index { get; set; }

        Entity.FileInfo _File { get; set; }

        IControl _ProgressLabel { get; set; }

        bool _IsHost { get; set; }

        bool _IsFullScreen { get; set; }

        public VideoPlay(System.Windows.Window form, IWindow parentWindow, System.Windows.Controls.Grid pagePanel, Dictionary<string, object> parameters)
        {
            Window = form;
            _PagePanel = pagePanel;
            _Parameters = parameters;
            ParentWindow = parentWindow;
            _Index = parentWindow as Index;
            MeetingId = _Parameters.GetValue<Guid>("MeetingId");
            _File = _Parameters.GetValue<Entity.FileInfo>("File");
            _IsHost = _Parameters.GetValue<bool>("IsHost");
            _IsFullScreen = _Parameters.GetValue<bool>("IsFullScreen");

            //_MeetingId = new Guid("195bd2ba-b58c-57c8-1aeb-dac76719409e");

            InitSet();

            initView();

            this.SetWindow();

            initLoad();
        }

        Dictionary<string,object> _FileNameBorder { get; set; }

        void initView()
        {
            this.SetTheme(_Index.UserInfo.Theme);
            var filesPanel = Utility.Common.GetProperty(_View, "FilesPanel");
            _FileNameBorder = filesPanel.GetValue<List<Dictionary<string, object>>>("properties").FirstOrDefault();
            filesPanel["properties"] = new List<Dictionary<string, object>>();

            var uniteOpen = Utility.Common.GetProperty(_View, "UniteOpen");
            uniteOpen["Text"] = "统一播放";
        }

        Controls.VlcPlayer _VlcPlayer1 { get; set; }

        Components.ScrollViewerComponent _Panel { get; set; }
        IControl _TipLabel1 { get; set; }
        IControl _UniteOpen { get; set; }
        IControl _UniteClose { get; set; }
        IControl _PlayDockPanel3 { get; set; }

        void initLoad()
        {
            _VlcPlayer1 = (Controls.VlcPlayer)GetControl("VlcPlayer1");
            _Panel = (Components.ScrollViewerComponent)GetComponent("ScrollViewer3");
            _VlcPlayer1.CloseVideo = () => closeVideo();
            _VlcPlayer1.CloseAction = () => UniteClose(null);
            _VlcPlayer1.SysncFullScreen = (isFullScreen) => sysncFullScreen(isFullScreen);
            _TipLabel1 = GetControl("TipLabel1");
            _UniteOpen = GetControl("UniteOpen");
            _UniteClose = GetControl("UniteClose");
            _ProgressLabel = GetControl("ProgressLabel");

            _PlayDockPanel3 = GetControl("PlayDockPanel3");

          

           // Window.PreviewKeyDown += Window_PreviewKeyDown;

        }
        
        private void Window_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == System.Windows.Input.Key.Escape && Grid.IsVisible && _VlcPlayer1 != null)
            {
                if (_VlcPlayer1.IsFullScreen) _VlcPlayer1.SetFullScreen();
                e.Handled = true;
            }
            else if (e.Key == System.Windows.Input.Key.F5 && Grid.IsVisible && _VlcPlayer1 != null)
            {
                if (!_VlcPlayer1.IsFullScreen) _VlcPlayer1.SetFullScreen();
                e.Handled = true;
            }
        }

        public void UniteOpen(IControl ctl)
        {
            var file = _SelectFile.Property.GetValue<Entity.FileInfo>("Data");
            file.MeetingId = MeetingId;
            Dictionary<string, object> data = new Dictionary<string, object>();
            data["File"] = file;
            var url = file.VideoType == 1 ? file.FilePath : file.FileUrl;
            if (file.VideoType == 1) _VlcPlayer1.Play(url, file.VideoType == 2);
            _Index.SendMessage("uniteOpen", data);
            this.Alert("统一打开指令已发出");
        }

        public void UniteClose(IControl ctl)
        {
            if (!_IsHost)
            {
                this._VlcPlayer1.Close();
            }
            else
            {
                var file = _SelectFile.Property.GetValue<Entity.FileInfo>("Data");
                file.MeetingId = MeetingId;
                Dictionary<string, object> data = new Dictionary<string, object>();
                data["File"] = file;
                _Index.SendMessage("uniteClose", data);
                if (ctl != null) this._VlcPlayer1.Close();
            }
        }

        public void ToBack(IControl ctl)
        {
            RevceToBack();

            if (_IsHost) _Index.SendMessage("videoToBack", null);
        }

        public void SetFullScreen()
        {
            _VlcPlayer1.SetFullScreen();
        }
        public void RevceToBack()
        {
            _VlcPlayer1.Close();
            _Index.VideoPlayToBack();
            _VlcPlayer1 = null;
            _IsClosed = true;
        }

        public bool RevceToBack(Entity.FileInfo file)
        {
            if (_SelectFile != null && _SelectFile.Property.GetValue<Guid>("FileId") == file.FileId)
            {
                RevceToBack();
                return true;
            }
            return false;
        }

        public void CloseVideo()
        {
            _VlcPlayer1.Close();
            _VlcPlayer1 = null;
            _IsClosed = true;
        }

        public void CloseVideo(Entity.FileInfo file)
        {
            if (_SelectFile != null && _SelectFile.Property.GetValue<Guid>("FileId") == file.FileId)
            {
                if (_VlcPlayer1 != null) _VlcPlayer1.Close();
            }
        }

        bool _IsClosed { get; set; }

        Entity.Meeting _Meeting { get; set; }

        public override void DataLoad()
        {
            base.DataLoad();

            _VlcPlayer1.SetWidth(_PlayDockPanel3.Element.ActualWidth);

            //getUserInfo();

            _Meeting = RequestService.GetMeetingDeviceUser(MeetingId);
            setHeaderInfo();

            var videoList = RequestService.GetMeetingVideos(MeetingId);
            setDataList(videoList);
        }

        string _VideoRightIcon { get { return "images/yxinmt_wpf/25040118011935236.png"; } }
        string _VideoRightIcon_red { get { return "images/yxinmt_wpf/25081900061941394.png"; } }

        void setDataList(List<Entity.FileInfo> dataList)
        {
            if (dataList == null || dataList.Count == 0) return;

            List<Dictionary<string, object>> dictList = new List<Dictionary<string, object>>();
            Dictionary<string, object> dict = null;
            List<Entity.PropertySet> propertyList = null;

            dataList.ForEach(d =>
            {
                propertyList = new List<Entity.PropertySet>();
                propertyList.Add(new Entity.PropertySet("TextBlock1", "Text", d.FileName));

                if(_File!= null && d.FileId== _File.FileId)
                {
                    propertyList.Add(new Entity.PropertySet("TextBlock1", "FontColor", "#0565FC"));
                    propertyList.Add(new Entity.PropertySet("FileNameButton", "BackColor", "#F2F9FF"));
                    if(_Index.UserInfo.Theme=="red") propertyList.Add(new Entity.PropertySet("Image2", "ImageUrl", _VideoRightIcon_red));
                    else propertyList.Add(new Entity.PropertySet("Image2", "ImageUrl", _VideoRightIcon));
                }

                dict = Utils.CloneDictionary(_FileNameBorder, propertyList);

                var properties = dict.GetValue<List<Dictionary<string, object>>>("properties");
                foreach (var p in properties)
                {
                    p["Data"] = d;
                    p["FileId"] = d.FileId;
                }

                dictList.Add(dict);
            });

            Dictionary<string, object> panel = new Dictionary<string, object>();
            panel.Add("name", "FilesPanel1");
            panel.Add("type", "StackPanel");
            panel.Add("properties", dictList);

            _Panel.LoadView(panel);
            _Panel.EventLoad();
            _Panel.DataLoad();

            _FileNameList = new List<IControl>();
            _Panel.ComponentList[0].ComponentList.ForEach(c =>
            {
                var f = c.ComponentList[0].ControlList[0];
                _FileNameList.Add(f);

                if (_File != null && f.Property.GetValue<Guid>("FileId") == _File.FileId)
                {
                    play(f.Property.GetValue<Entity.FileInfo>("Data"), (Controls.StackPanelButton)f);
                }
            });
        }

        List<IControl> _FileNameList { get; set; }

        Controls.StackPanelButton _SelectFile { get; set; }

        public void PlayVideo2(bool isHost, Entity.FileInfo file)
        {
            if (_FileNameList == null) return;
            _IsHost = isHost;
            foreach (var item in _FileNameList)
            {
                var btn = (Controls.StackPanelButton)item;
                if (item.Property.GetValue<Guid>("FileId") == file.FileId)
                {
                    if (_Index.UserInfo.Theme == "red")
                    {
                        btn.SetPanelBackColor("#FFEBEB");
                        btn.SetFontColor("#EA0000");
                        btn.SetImageUrl(_VideoRightIcon_red);
                    }
                    else
                    {
                        btn.SetPanelBackColor("#F2F9FF");
                        btn.SetFontColor("#0565FC");
                        btn.SetImageUrl(_VideoRightIcon);
                    }

                    play(file, btn);
                }
                else
                {
                    btn.SetPanelBackColor("#ffffff");
                    btn.SetFontColor("#2A2A2A");
                    btn.SetImageUrl(string.Empty);
                }
            }
        }

        public void PlayVideo(IControl ctl)
        {
            if (ctl == _SelectFile) return;

            foreach (var item in _FileNameList)
            {
                var btn = (Controls.StackPanelButton)item;
                if (ctl == item)
                {
                    if (_Index.UserInfo.Theme == "red")
                    {
                        btn.SetPanelBackColor("#FFEBEB");
                        btn.SetFontColor("#EA0000");
                        btn.SetImageUrl(_VideoRightIcon_red);
                    }
                    else
                    {
                        btn.SetPanelBackColor("#F2F9FF");
                        btn.SetFontColor("#0565FC");
                        btn.SetImageUrl(_VideoRightIcon);
                    }

                    play(ctl.Property.GetValue<Entity.FileInfo>("Data"), btn);
                }
                else
                {
                    btn.SetPanelBackColor("#ffffff");
                    btn.SetFontColor("#2A2A2A");
                    btn.SetImageUrl(string.Empty);
                }
            }
        }

        void closeVideo()
        {
            if (_SelectFile != null)
            {
                _SelectFile.SetPanelBackColor("#ffffff");
                _SelectFile.SetFontColor("#2A2A2A");
                _SelectFile.SetImageUrl(string.Empty);

                _TipLabel1.SetVisible(false);
                _UniteOpen.SetVisible(false);
                _UniteClose.SetVisible(false);

                //if (_IsHost)
                //{
                //    var file = _SelectFile.Property.GetValue<Entity.FileInfo>("Data");
                //    file.MeetingId = MeetingId;
                //    Dictionary<string, object> data = new Dictionary<string, object>();
                //    data["File"] = file;
                //    _Index.SendMessage("uniteClose", data);
                //}

                _SelectFile = null;
            }
        }

        public void SynscFullScreen2(Dictionary<string, object> data)
        {
            bool isFullScreen = data.GetValue<bool>("IsFullScreen");
            Guid fileId = data.GetValue<Guid>("FileId");
            if (_SelectFile != null && fileId == _SelectFile.Property.GetValue<Guid>("FileId"))
            {
                if (isFullScreen != _VlcPlayer1.IsFullScreen) _VlcPlayer1.SetFullScreen();
            }
        }

        void sysncFullScreen(bool isFullScreen)
        {
            Dictionary<string, object> data = new Dictionary<string, object>();
            data["IsFullScreen"] = isFullScreen;
            data["FileId"] = _SelectFile.Property.GetValue<Guid>("FileId");

            if (_IsHost) _Index.SendMessage("sysncFullScreen", data);
        }


        void play(Entity.FileInfo file, Controls.StackPanelButton btn)
        {
            Task.Run(() =>
            {
                if (_VlcPlayer1 != null)
                {
                    lock (_lock)
                    {
                        Window.Dispatcher.Invoke(() =>
                        {
                            _VlcPlayer1.Close();
                        });
                    }
                }

                if (file.VideoType == 2 || _Index.UserInfo.DeviceType == 3)
                {
                    play2(file, btn);
                    return;
                }

                if (UploadDownload.JudgeComplete(file))
                {
                    play2(file, btn);
                }
                else
                {
                    UploadDownload.DownloadFile(MeetingId, file, (p) =>
                    {
                        if (_IsClosed) return;
                        Task.Run(() =>
                        {
                            Window.Dispatcher.Invoke(() =>
                            {
                                if (p.Percentage == 100)
                                {
                                    Thread.Sleep(200);
                                    _ProgressLabel.SetVisible(false);
                                }
                                else
                                {
                                    string size1 = Utility.Common.GetFileSize(p.SentBytes);
                                    string size2 = Utility.Common.GetFileSize(p.TotalBytes);
                                    string message = $"正在下载中，已下载：{size1}/{size2}，下载进度：{p.Percentage}%";
                                    _ProgressLabel.SetVisible(true);
                                    _ProgressLabel.SetValue(message);
                                }
                            });
                        });

                    }, (filePath) =>
                    {
                        if (_IsClosed) return;

                        if (!string.IsNullOrEmpty(file.Message))
                        {
                            Alert(file.Message);
                            return;
                        }
                        if (string.IsNullOrEmpty(filePath)) return;

                        UploadDownload.ProgressCallback2 = null;
                        UploadDownload.Complete = null;
                        play2(file, btn);
                    });
                }
            });
        }

        object _lock = new object();

        Entity.FileInfo _SelectFileInfo { get; set; }
        Controls.StackPanelButton _SelectButton{ get; set; }

        System.Collections.Concurrent.ConcurrentStack<Tuple<Entity.FileInfo, Controls.StackPanelButton>> _StackPlayFile = new System.Collections.Concurrent.ConcurrentStack<Tuple<Entity.FileInfo, StackPanelButton>>();

        void play2(Entity.FileInfo file, Controls.StackPanelButton btn)
        {
            Task.Run(() =>
            {
                Tuple<Entity.FileInfo, Controls.StackPanelButton> element = new Tuple<Entity.FileInfo, StackPanelButton>(file, btn);
                _StackPlayFile.Push(element);
                if (_StackPlayFile.Count == 1)
                {
                    play3(file, btn);
                }
            });
        }

        void play3(Entity.FileInfo file, Controls.StackPanelButton btn)
        {
            Task.Run(() =>
            {
                Thread.Sleep(1000);
                lock (_lock)
                {
                    Window.Dispatcher.Invoke(() =>
                    {
                        try
                        {
                            var url = file.VideoType == 1 ? file.FilePath : file.FileUrl;

                            if (_Index.UserInfo.DeviceType == 3 && file.VideoType == 1)
                            {
                                var slices = RequestService.GetMeetingSubjectFileSlices(file.FileId);
                                if (slices.Count == 1) url = _Index.ClientConfig.ServiceUrl + slices[0].FileUrl;
                                else url = _Index.ClientConfig.ServiceUrl + "/res/" + MeetingId + "/" + file.FileMd5 + "/" + file.FileName;
                            }

                            if (file.VideoType == 2) _VlcPlayer1.PlayLive(url, this, _TipLabel1, "双击视频：全屏/还原；");
                            else _VlcPlayer1.Play(url, file.VideoType == 2);
                            _VlcPlayer1.SetVisible(true);
                            if (_Index.UserInfo.DeviceType == 3)
                            {
                                _VlcPlayer1.IsFullScreen = false;
                                _VlcPlayer1.SetFullScreen();
                            }
                            else
                            {
                                if (file.VideoType == 1) _TipLabel1.SetValue("双击视频：全屏/还原；单击视频显示底部进度栏");
                                _TipLabel1.SetVisible(true);
                                if (_IsHost)
                                {
                                    _UniteClose.SetValue("统一关闭");
                                    _UniteOpen.SetVisible(true);
                                    _UniteClose.SetVisible(true);
                                }
                                else if(file.VideoType == 2)
                                {
                                    _UniteClose.SetValue("关闭");
                                    _UniteClose.SetVisible(true);
                                }
                            }
                            _SelectFile = btn;
                        }
                        catch (Exception ex)
                        {
                            _VlcPlayer1.Close();
                            Alert(ex.Message);
                            Utility.LoggerProxy.Exception(Name, "play", ex);
                        }

                        if (_StackPlayFile.Count == 1)
                        {
                            _StackPlayFile.Clear();
                        }
                        else
                        {
                            Tuple<Entity.FileInfo, Controls.StackPanelButton> element = null;
                            _StackPlayFile.TryPeek(out element);
                            if (element != null)
                            {
                                play3(element.Item1, element.Item2);
                                _StackPlayFile.Clear();
                                _StackPlayFile.Push(element);
                            }
                        }
                    });
                }
            });
        }

        public void SetVisible(bool v)
        {
            if (v) _VlcPlayer1.Play();
            else _VlcPlayer1.Pause();
            Grid.Visibility = v ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
        }

        void setHeaderInfo()
        {
            var userNamePanel = (Controls.StackPanelButton)GetControl("UserNamePanel");
            var title = GetControl("Title");
            if (_Meeting != null)
            {
                userNamePanel.SetLabelText(_Meeting.UserName ?? "匿名");
                title.SetValue(_Meeting.Title);
            }
        }
    }
}
